/**
 * 1. 向store发送post请求 body内为商品信息
 * 2. 向BOS上传商品文件
 *    2.1 检查product_info 长度 若为1，则直接上传 若>1 压缩后上传
 *    2.2 上传
 * 3. 上传完成 写数据库
 */

var logger = require('log4js').getLogger();
var zip = require('../../../common/zip');
var config = require('../../../config.json');
var fs = require('fs');
var path = require('path');
var request = require('request');
var http = require('http');
var tools = require('../../../common/tools.js');
var url = require('url');
var PublishProxy = require('../../../proxy/publish.js');
var EventProxy = require('eventproxy');
var uuid = require('uuid');

var ep = new EventProxy();

var publish_info = {};


ep.fail(function (err) {
    return res.format_json(null, 500, err);
});

var getPostData = function (body) {
    var product_info = [];
    body.productsInfo.map(function (product) {
        product_info.push({
            "type": product.type,
            "version": product.version,
            "name": product.name,
            "fileName": path.basename(product.file)
        });
    });

    var publishInfo = {
        "name": body.publishName,
        "version": body.version,
        "publish_config": body.publishConfig_id,
        "product_info": product_info,
        "description": body.publishDescription
    };
    var goodsInfo = {
        "custom_data": body.custom_data,
        "img": body.goods_img,
        "introduction": body.goods_intro,
        "name": body.goodsName,
        "privacy": body.privacy,
        "supplier": body.supplier,
        "title": body.goodsTitle,
        "type": body.type,
        "version": body.version,
        "tag": body.tags,
        "dependency": body.goods_dependencies
    };
    return {publishInfo: publishInfo, goodsInfo: goodsInfo}
};

var upload = function (name, filePath,type,version, cb) {
    request.get({
        url: config.store.store_private + "/store/create_upload?name=" + name + "&version="+ version +"&type=" + type,
        agentOptions: {
            secureProtocol: 'SSLv3_method'
        }
    }, function (error, response, body) {
        if (!error && response.statusCode == 200) {
            body = JSON.parse(body);
            if (body && body.data && body.data.url) {
                var href = url.parse(body.data.url);
                var toOptions = {
                    hostname: href.hostname,
                    port: href.port,
                    path: href.path,
                    method: 'PUT'
                };
                var file_Size = fs.statSync(filePath).size;
                var put_request = http.request(toOptions, function (response) {
                    logger.info(response.statusCode);
                    return cb(null, response.statusCode);
                }).on('error', function (e) {
                    logger.error('error' + e);
                    return cb(e);
                });
                var totalSize = file_Size;
                var passedLength = 0;
                var rs = fs.createReadStream(filePath, {autoClose: true});
                rs.on('data', function(chunk) {
                    passedLength += chunk.length;
                });
                setTimeout(
                    function show() {
                    var percent = Math.ceil((passedLength / totalSize) * 100);
                    if (passedLength < totalSize) {
                        PublishProxy.updatePublishState(publish_info._id, percent + '%' , function () {
                            messageBroker.emit('publish_state_update', {
                                body: { msg:  percent + '%  ' },
                                err: null
                            });
                            messageBroker.emit('product_uploading', {
                                body: {publish_id: publish_info._id, msg:  percent + '%  '},
                                err: null
                            });
                            setTimeout(show, 500);
                        });
                    }
                },500);
                rs.pipe(put_request);
            }
        }else{
            var err = error || response.statusCode;
            logger.error('error occurred when upload the product:' + err);
            return cb(err);
        }

    })
};

var upload_product_files = function (body, publish_id, type) {
    var productsInfo = body.productsInfo;
    var products = productsInfo;
    var targetPath;
    try {
        fs.accessSync(config.publish_temp, fs.R_OK);
    } catch (e) {
        fs.mkdirSync(config.publish_temp);
    }
    if (type == "mk") {
        if (productsInfo.length > 0) {
            var sourceFiles = [];
            products.map(function (product) {
                try {
                    fs.accessSync(product.file, fs.R_OK);
                } catch (e) {
                    PublishProxy.updatePublishState(publish_id, "product_error", function () {
                        messageBroker.emit('publish_state_update', {body: {state: "product_error"}, err:null});
                        messageBroker.emit(publish_id, {task_id: publish_id, body: null, err: {msg:'商品上传失败'}});
                        logger.error(err);
                    });
                    return false;
                }
                sourceFiles.push(product.file);
            });
            targetPath = path.join(config.publish_temp, body.goodsName + '.zip');
            zip.zipFiles(sourceFiles, targetPath, function (err, data) {
                if (err) {
                    PublishProxy.updatePublishState(publish_id, "product_error", function () {
                        messageBroker.emit('publish_state_update', {body: {state: "product_error"}, err:null});
                        messageBroker.emit(publish_id, {task_id: publish_id, body: null, err: {msg:'商品上传失败'}});
                        logger.error(err);
                    });
                    return false;
                }
                try {
                    fs.accessSync(targetPath, fs.R_OK);
                } catch (e) {
                    console.error('压缩结果不存在:' + targetPath);
                }
                PublishProxy.updatePublishState(publish_id, "products_prepared", function () {
                    messageBroker.emit('publish_state_update', {body: {state: "products_prepared"}, err:null});
                        upload(body.goodsName, path.join(config.publish_temp, body.goodsName + '.zip'), "mk", body.version, function (error, result) {
                            if (error) {
                                PublishProxy.updatePublishState(publish_id, "upload_failed", function () {
                                    messageBroker.emit('publish_state_update', {body: {state: "upload_failed"}, err:null});
                                    messageBroker.emit(publish_id, {task_id: publish_id, body: null, err: {msg:'商品上传失败'}});
                                    logger.error(error);
                                })
                            }
                            if (200 == result) {
                                PublishProxy.updatePublishState(publish_id, "uploaded", function () {
                                    messageBroker.emit('publish_state_update', {body: {state: "uploaded"}, err:null});
                                    messageBroker.emit(publish_id, {task_id: publish_id, body: {msg:'商品发布完成'}, err: null});
                                    logger.info('文件上传成功');
                                })
                            }
                        })
                    }
                );
            });
        } else {
            logger.error("商品中不包含任何产品！");
            PublishProxy.updatePublishState(publish_id, "product_error", function () {
                messageBroker.emit('publish_state_update', {body: {state: "product_error"}, err:null});
                messageBroker.emit(publish_id, {task_id: publish_id, body: null, err: {msg:'商品上传失败'}});
            });
        }
    } else if (type = "app") {
        if (body.productsInfo.length > 0) {
            var sourceFile = products[0].file;
            var product_type = products[0].type;
            targetPath = path.join(config.publish_temp, body.goodsName);
            zip.unzip(sourceFile, targetPath, function (err, data) {
                if (err) {
                    PublishProxy.updatePublishState(publish_id, "product_error", function () {
                        messageBroker.emit('publish_state_update', {body: {state: "product_error"}, err:null});
                        messageBroker.emit(publish_id, {task_id: publish_id, body: null, err: {msg:'商品上传失败'}});
                        logger.error(err);
                    });
                    return false;
                }
                try {
                    fs.accessSync(targetPath, fs.R_OK);
                } catch (e) {
                    PublishProxy.updatePublishState(publish_id, "product_error", function () {
                        messageBroker.emit('publish_state_update', {body: {state: "product_error"}, err:null});
                        messageBroker.emit(publish_id, {task_id: publish_id, body: null, err: {msg:'商品上传失败'}});
                        logger.error(err);
                    });
                    return false;
                }
                var name = body.goodsName;
                var file_type;
                switch (product_type) {
                    case "app_android":
                        file_type = "apk";
                        break;
                    case "app_ios":
                        file_type = "ipa";
                        break;
                }
                PublishProxy.updatePublishState(publish_id, "products_prepared", function () {
                    messageBroker.emit('publish_state_update', {body: {state: "products_prepared",msg:"开始上传商品"}, err:null});
                        upload(name, path.join(config.publish_temp, name, "nectar." + file_type), product_type, body.version,function (error, result) {
                            if (error) {
                                PublishProxy.updatePublishState(publish_id, "upload_failed", function () {
                                    messageBroker.emit('publish_state_update', {body: {state: "upload_failed"}, err:null});
                                    messageBroker.emit(publish_id, {task_id: publish_id, body: null, err: {msg:'商品上传失败'}});
                                    logger.error(error);
                                })
                            }
                            if (200 == result) {
                                PublishProxy.updatePublishState(publish_id, "uploaded", function () {
                                    messageBroker.emit('publish_state_update', {body: {state: "uploaded"}, err:null});
                                    messageBroker.emit(publish_id, {task_id: publish_id, body: {'msg':'商品发布成功'}, err: null});
                                    logger.info('文件上传成功');
                                })
                            }
                        })
                    }
                );
            });
        } else {
            PublishProxy.updatePublishState(publish_id, "product_error", function () {
                messageBroker.emit('publish_state_update', {body: {state: "product_error"}, err:null});
                logger.error("商品中不包含任何产品！");
            });
        }
    }
};
var publish_to_store = function (publish_id, goodsInfo,cb) {
    request.post({
        url: config.store.store_private + "/store/good",
        form: goodsInfo
    }, function (e, r, body) {
        if (e) {
            PublishProxy.updatePublishState(publish_id, "publish_failed", function () {
                messageBroker.emit('publish_state_update', {body: {state: "publish_failed"}, err:null});
                messageBroker.emit(publish_id, {task_id: publish_id, body: null, err: {msg:'商品发布到store失败'}});
                logger.error("发布到store失败：" + JSON.stringify(e));
            });
            return false;
        }
        logger.info("发布到store成功：" + JSON.stringify(r));
        PublishProxy.updatePublishState(publish_id, "published", cb);
    });
};


var mk_publish = function (req, res) {
    var body = req.body;
    var publishInfo = getPostData(body).publishInfo;
    var goodsInfo = getPostData(body).goodsInfo;
    ep.after("publish_created", 1, function (publish_id) {
        publish_to_store(publish_id[0], goodsInfo,function () {
            upload_product_files(body, publish_id[0], "mk");
        });
    });
    publishInfo.state = "publish_created";
    PublishProxy.addPublishInfo(publishInfo, function (err, data) {
        if (err) {
            logger.error(err);
            return res.format_json(null, 500, "发布任务发起失败：" + JSON.stringify(err));
        }
        logger.info("发布任务发起成功：" + JSON.stringify(data));
        messageBroker.emit('publish_state_update', {body: {state: "publish_created"}, err:null});
        ep.emit("publish_created", JSON.parse(JSON.stringify(data))._id);
        return res.format_json({'msg':"商品发布任务发起成功!",'task_id':JSON.parse(JSON.stringify(data))._id}, 200);
    });
};

app_publish = function (req, res) {
    var body = req.body;
    var publishInfo = getPostData(body).publishInfo;
    var goodsInfo = getPostData(body).goodsInfo;
    //var task_id = uuid.v1();
    goodsInfo.type = body.productsInfo[0].type;
    ep.after("publish_created", 1, function () {
        publish_to_store(publish_info._id, goodsInfo,function () {
            upload_product_files(body, publish_info._id, "app");
        });
    });
    publishInfo.state = "publish_created";
    PublishProxy.addPublishInfo(publishInfo, function (err, data) {
        if (err) {
            logger.error(err);
            return res.format_json(null, 500, "商品发布任务发起失败：" + JSON.stringify(err));
        }
        publish_info = data;
        messageBroker.emit('publish_state_update', {body: {state: "publish_created"}, err:null});
        logger.info("发布任务发起成功：" + JSON.stringify(data));
        ep.emit("publish_created");
        return res.format_json({'msg':"商品发布任务发起成功!",'task_id':JSON.parse(JSON.stringify(data))._id}, 200);
    });
};

//core_node_publish = function(req, res){
//
//};
//
//core_java_publish = function(req, res){
//
//};

exports.publish = function (req, res, next) {
    var body = req.body;
    switch (body.type) {
        case "mk":
            mk_publish(req, res);
            break;
        case "app":
            app_publish(req, res);
            break;
        case "core_node":
            //core_node_publish(req, res);
            break;
        case "core_java":
            //core_java_publish(req, res);
            break;
        case "app_plugin":
            var plugin_publish = require('./nectar_plugin_publish.js').publish;
            plugin_publish(req,res);
            break;
        default:
            return res.format_json(null, 500, "错误的商品类型！")
    }

};

exports.getPublishRec = function (req, res, next) {
    var cfg_id = req.params.publishConfig_id;
    PublishProxy.getPublishRec(cfg_id, function (err, data) {
        if (err) {
            logger.error(err);
            return res.format_json(null, 500, err);
        }
        return res.format_json(data);
    });
};

exports.deletePublishRec = function (req, res, next) {
    var publish_id = req.params.publish_id;
    PublishProxy.deletePublishRec(publish_id, function (err, data) {
        if (err) {
            logger.error(err);
            return res.format_json(null, 500, err);
        }
        return res.format_json(data);
    });
};
